/**
 *   Copyright (c) fanguangping. All rights reserved.
 *   The use and distribution terms for this software are covered by the
 *   Eclipse Public License 1.0 (http://opensource.org/licenses/eclipse-1.0.php)
 *   which can be found in the file epl-v10.html at the root of this distribution.
 *   By using this software in any fashion, you are agreeing to be bound by
 * 	 the terms of this license.
 *   You must not remove this notice, or any other, from this software.
 **/
package org.jfunny.core.ds;

import java.util.ArrayList;
import java.util.List;

/**
 * 循环节点，表示 【 与 】 括起来的部分
 * 
 * @author fanguangping
 *
 */
public class Loop implements Statement {
	public static final int ZERO_ONE = 0; //【】?模式
	public static final int ZERO_MORE = 1; //【】*模式
	public static final int ONE_MORE = 2; //【】+模式

	public static final String PAREN_L = "【";
	public static final String PAREN_R = "】";

	public Loop(int type) {
		this.type = type;
	}

	private ArrayList<Statement> statements = new ArrayList<Statement>();

	public boolean equals(Object obj) {
		return (obj != null) && (obj instanceof Loop) && (((Loop) obj).type == type)
				&& ((Loop) obj).equalArgs(statements);
	}

	public String toString() {
		String str = PAREN_L;
		for (Statement s : statements) {
			str += s;
		}
		str += PAREN_R;
		if (type == ZERO_ONE) {
			str += "?";
		}
		else if (type == ZERO_MORE) {
			str += "*";
		}
		else if (type == ONE_MORE) {
			str += "+";
		}

		return str;
	}

	/**
	 * 判断是否有其中一个Arg是相等的
	 * @param statements
	 * @return
	 */
	public boolean equalArgs(ArrayList<Statement> statements) {
		if (this.statements == null || statements == null) {
			return false;
		}
		if (this.statements.size() == 0 && statements.size() == 0) {
			return true;
		}

		boolean equal = false;

		Arg arg = null;
		for (Statement s : statements) {
			if (s instanceof Arg) {
				arg = (Arg) s;
			}
		}

		for (Statement s : this.statements) {
			if (s instanceof Arg && s.toString().equals(arg.toString())) {
				equal = true;
			}
		}

		return equal;
	}

	private final int type;
	public int matchTimes = 0;

	public int getType() {
		return type;
	}

	public boolean addChild(Statement statement) {
		return statements.add(statement);
	}

	public boolean removeChild(Statement statement) {
		return statements.remove(statement);
	}

	public List<Statement> getChildren() {
		return statements;
	}

	public void setChildren(ArrayList<Statement> statements) {
		this.statements = statements;
	}
}
